#ifndef __DOUBLELINKVOID_H_
#define __DOUBLELINKVOID_H_
#include <iostream>

class DoubleLinkList
{
public:
    using ElementType = void *;
    DoubleLinkList();

    void SetFreePtr(void (*FreePtr)(ElementType))
    {
        this->FreePtr = FreePtr;
    }
    void SetShowPtr(void (*ShowPtr)(ElementType))
    {
        this->ShowPtr = ShowPtr;
    }

    // 插入
    void InsertTail(const ElementType &element);
    void InsertHead(const ElementType &element);

    // 中间插
    void InsertByIndex(int index, const ElementType element);
    // 按位置删
    void RemoveByIndex(int index);
    // 按值删
    void RemoveByElement(const ElementType &element);
    // void* 回调版本
    int Size()
    {
        return size;
    }

    // 查找
    ElementType *back()
    {
        return &tail->data;
    }

    ElementType *Head()
    {
        return &head->next->data;
    }

    ~DoubleLinkList();
    void show();

private:
    struct Node
    {
        Node(const ElementType &data) : data(data), prev(nullptr), next(nullptr) {}
        ElementType data;
        Node *next;
        Node *prev; // 前置指针
    };

    Node *head; // 头指针
    Node *tail; // 尾指针
    int size;

    void (*FreePtr)(ElementType);
    void (*ShowPtr)(ElementType);
};

#endif